\documentclass[UTF8]{ctexbeamer}
\usepackage{listings}
\usepackage{fontspec}
\usepackage{xcolor}
\usepackage{url}
\usepackage{hyperref}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{arrows.meta}
\usepackage{colortbl}
\usepackage{tabu}

%% listings config
\lstset{
  columns=fixed,
  language=java,
  numbers=left,
  numberstyle=\tiny,
  basicstyle=\small
}

\begin{document}

\begin{frame}
  \title{Actors编程模型} \author{sren} \date{\today}
  \maketitle
\end{frame}

\begin{frame}
  \begin{center}目录\end{center}
  \normalsize
  \tableofcontents
\end{frame}

\section{Actors模型}
\frame{\tableofcontents[currentsection]} % 在每个章节前显示当前章节在目录中的位置

\begin{frame}{actor模型}
  Actor模型是一种并发模型，通过组件方式定义并发编程范式的高级阶段，避免使用者接
  触多线程并发或线程池等基础概念，简化并发程序的开发难度。\\
\end{frame}

\tikzstyle{actor} = [circle, draw, fill=blue!50, text centered, align=center]
\tikzstyle{msg} = [rectangle, draw, fill=blue!80!green!30, text centered]
\tikzstyle{line} = [draw, -{Latex[length=3mm]}]

\begin{frame}{actor模型}
  \begin{center}
    \begin{tikzpicture}[node distance=2cm, auto]
      \node[msg] (m1) {Mail Box};
      \node[actor, below of=m1] (A1) {Actor1};
      \node[msg, right of=m1, node distance=4cm] (m2) {Mail Box};
      \node[actor, below of=m2] (A2) {Actor2};
      \node[actor, above of=m1, right=1.25cm] (a3) {Actor3};
      \node[msg, above of=a3] (m3) {Mail Box};

      \path [line] (m1) -> (A1);
      \path [line] (A1) -- (-1.5,-2) -- (-1.5, 4) ->  (m3);
      \path [line] (m2) -> (A2);
      \path [line] (A2) -> (5.5, -2) -- (5.5, 4) ->  (m3);
      \path [line] (m3) -> (a3);
      \path [line] (a3) -- (m3);
      \path [line] (a3) -> (m1);
      \path [line] (a3) -> (m2);
    \end{tikzpicture}
  \end{center}
\end{frame}

\begin{frame}{actor模型}
  基本概念：
  \begin{itemize}
  \item actor:\\
    actor是一个轻量级的实体，用来接收事件并对事件进行处理。actor可以是有状态或无状态的。
  \item message:\\
    message是actor之间传递的信息/命令/事件等，在actor模型中，message是不可变的。
  \item mailbox:\\
    mailbox是用来存储消息的队列，actor会从mailbox获取消息并处理。
  \end{itemize}
\end{frame}

\begin{frame}{actor模型}
  基本概念: 
  \begin{itemize}
  \item 并行/并发 \\
    并行是系统同时执行多个任务，并发是系统分时执行多个任务
  \item 异步/同步 \\
    同步是调用者需要等待返回，期间不做任何事情。
    异步是调用者不等待返回，继续做其他事情，当有返回信息时再具体处理。
  \end{itemize}
\end{frame}

\section{多线程模型}
\frame{\tableofcontents[currentsection]} % 在每个章节前显示当前章节在目录中的位置

\begin{frame} {传统的线程模型}
  进程，线程，线程池，协程：
  \begin{itemize}
  \item 进程： 操作系统管理的并行执行的单元，由操作系统负责调度。
  \item 线程：同一个软件内的多个并行执行单元，由软件负责调度。
  \item 线程池：为了避免创建新线程而建立的池，软件调度。
  \item 协程：用户控制的代码逻辑编排，避免了block等待问题。
  \end{itemize}
\end{frame}

\begin{frame} {传统的线程模型}
  \begin{center}
    \tikzstyle{os} = [rectangle, draw, fill=green!100!red!10]
    \tikzstyle{process} = [rectangle, draw, fill=green!50]
    \tikzstyle{line} = [draw, -{Latex[length=3mm]}]
    \begin{tikzpicture}[node distance=2cm, auto]
      \node[os, minimum width=10cm,minimum height=6cm] {};
      \node at (0, 2.5) {APP, 线程调度};
      \node[process, minimum width=1cm, minimum height=5cm] at (-2.5, -0.3) (t1) {线程1};
      \node[process, minimum width=1cm, minimum height=5cm] at (2.5, -0.3) (t2) {线程2};
      \node[draw] at (0, 1) (r1) {资源1};
      \node[draw] at (0, -1) (r2) {资源2};
      \path[line]  (t1) -- (r1);
      \path[line]  (r1) -> (t2);
      \path[line]  (t2) -> (r2);
      \path[line]  (r2) -> (t1);
    \end{tikzpicture}
  \end{center}
\end{frame}

\begin{frame} {actor与传统多线程模型的区别}
  \begin{center}
    \begin{tabular}{|c|c|c|} \hline
      \rowcolor{black!30} & actor模型 & 多线程模型 \\ \hline
      \cellcolor{green!40} 通信机制 & message+mailbox & 共享内存 \\ \hline
      \cellcolor{green!40} 执行单元 & actor类 & Runnable接口  \\ \hline
      \cellcolor{green!40} 调度 & 不需要 & 线程池 \\ \hline
    \end{tabular}
  \end{center}
\end{frame}

\tikzstyle{thread} = [rectangle, draw, fill=green!70!red!20, text centered, align=center]
\begin{frame}{actor模型并发实现}
  \begin{center}
    \begin{tikzpicture}[node distance=2cm]
      \node [actor] (ma) {Map\\Actor} ;

      \node [msg, right of=ma, node distance=2.5cm] (m1) {msg...} ;
      \node [msg, above of=m1] (m2) {msg...} ;
      \node [msg, below of=m1] (m3) {msg...} ;
      \node [below of=m1, node distance=1cm] {...};

      \node [actor, right of=m1] (a1) {actor1};
      \node [actor, right of=m2] (a2) {actor2};
      \node [actor, right of=m3] (a3) {actor3};
      \node [below of=a1, node distance=1cm] {...};

      \node [msg, right of=a1] (mn) {msg...};
      \node [actor, right of=mn] (an) {Reduce\\Actor};

      \node [below right of=a3] (temp1) {};
      \node [thread, right of=temp1,minimum width=3cm] (t1) {thread 1};
      \node [thread, below right of=t1, node distance=1cm, minimum width=3cm] (tn) {thread n};
      
      
      \path[line] (ma) -- (m1);
      \path[line] (ma) -- (m2);
      \path[line] (ma) -- (m3);
      \path[line] (m1) -- (a1);
      \path[line] (m2) -- (a2);
      \path[line] (m3) -- (a3);
      \path[line] (a1) -- (mn);
      \path[line] (a2) -- (mn);
      \path[line] (a3) -- (mn);
      \path[line] (mn) -- (an);

      \path[line, dashed] (a1) -- (t1);
      \path[line, dashed] (a2) -- (tn);
      \path[line, dashed] (a3) -- (tn);
      
    \end{tikzpicture}
  \end{center}
\end{frame}

\begin{frame}

  \begin{center}
    消息的 {\LARGE 不可变} 性 \\
    \vspace{1em}
    actor发送到mailbox的message是不可变的。\\
    \vspace{1cm}
    \begin{tabular}{rl}
      vertX: & message必须是String类型 \\
      AKKA in Java: & 使用final关键字\\
      AKKA in Scala: & 使用case class \\
    \end{tabular}
\end{center}
\end{frame}

\section{Actor模型的现实意义}
\frame{\tableofcontents[currentsection]} % 在每个章节前显示当前章节在目录中的位置

\begin{frame}
  \begin{center}
  \begin{itemize}
  \item Actor --> things
    \item message --> message
    \end{itemize}
  \end{center}
\end{frame}

\begin{frame}
  例子：\\
  Actor -> 人 \\
  message -> 工作任务

  \begin{tikzpicture}[node distance=2.5cm]
    \node[actor] (a1) {员工1};
    \node[actor, right of=a1] (a2) {员工2};
    \node[actor, right of=a2] (a3) {员工3};
    \node[msg, above of=a1, node distance=1.8cm] (m1) {任务列表1};
    \node[msg, above of=a2, node distance=1.8cm] (m2) {任务列表2};
    \node[msg, above of=a3, node distance=1.8cm] (m3) {任务列表3};

    \node[actor, above of=m2] (m) {管理员};
    \path[line] (m) -- (m1);
    \path[line] (m) -- (m2);
    \path[line] (m) -- (m3);
    \path[line] (m1) -- (a1);
    \path[line] (m2) -- (a2);
    \path[line] (m3) -- (a3);
  \end{tikzpicture}
\end{frame}

\begin{frame}
  例子：\\
  Actor -> 服务器/设备/软件模块 \\
  message -> 监控信息
  \begin{tikzpicture}[node distance=3cm]
    \node[actor] (a1) {服务器1};
    \node[actor, right of=a1] (a2) {设备2};
    \node[actor, right of=a2] (a3) {软件模块3};
    \node[msg, above of=a1, node distance=1.8cm] (m1) {redis/mq};
    \node[msg, above of=a2, node distance=1.8cm] (m2) {redis/mq};
    \node[msg, above of=a3, node distance=1.8cm] (m3) {redis/mq};
    \node[actor, above of=m2] (m) {监控};
    \path[line] (m) -- (m1);
    \path[line] (m) -- (m2);
    \path[line] (m) -- (m3);
    \path[line] (m1) -- (a1);
    \path[line] (m2) -- (a2);
    \path[line] (m3) -- (a3);
  \end{tikzpicture}

\end{frame}


\begin{frame}
  例子：\\
  Actor -> dispatcher \\
  message -> worker thread \\
  
  \begin{tikzpicture}[node distance=3cm]
    \node[actor] (a1) {thread 1};
    \node[actor, right of=a1] (a2) {thread 2};
    \node[actor, right of=a2] (a3) {thread 3};
    \node[msg, above of=a1, node distance=1.8cm] (m1) {queue};
    \node[msg, above of=a2, node distance=1.8cm] (m2) {queue};
    \node[msg, above of=a3, node distance=1.8cm] (m3) {queue};
    \node[actor, above of=m2] (m) {dispatcher};
    \path[line] (m) -- (m1);
    \path[line] (m) -- (m2);
    \path[line] (m) -- (m3);
    \path[line] (m1) -- (a1);
    \path[line] (m2) -- (a2);
    \path[line] (m3) -- (a3);
  \end{tikzpicture}
\end{frame}

% \section {actor模型与物联网}
% \frame{\tableofcontents[currentsection]} % 在每个章节前显示当前章节在目录中的位置

\section {actor模型的应用}
\frame{\tableofcontents[currentsection]} % 在每个章节前显示当前章节在目录中的位置

\begin{frame}{actor模型的典型应用}
  \begin{itemize}
  \item  网络游戏服务端：actor -> npc, player ...  \\
  \item  物联网： actor -> 物联网内的各种设备 \\
  \item  集群计算： actor -> task/thread/process
  \end{itemize}
\end{frame}

\tikzstyle{box} = [rectangle, draw, text centered, align=center]
\tikzstyle{lined} = [draw,  {Latex[length=3mm]}-{Latex[length=3mm]}]
\begin{frame}{系统监控}
  actor -> 被监控的设备/模块
  \begin{center}
    \begin{tikzpicture}
      \node[box, fill=green!50, minimum width=6cm, minimum height=4cm] at(0,0) (m) {\ 监控系统 \\\\\\\\\\};
      \node[box, fill=blue!40] at (-6, 1.5) (d1) {被监控模块1};
      \node[box, fill=blue!40] at (-6, 0) (d2) {被监控模块2};
      \node[box, fill=blue!40] at (-6, -1.5) (d3) {被监控模块3};
      
      \node[box, fill=blue!25] at (-2, 0.5) (a1) {actor1};
      \node[box, fill=blue!25] at (-2, -0.5) (a2) {actor2};
      \node[box, fill=blue!25] at (-2, -1.5) (a3) {actor3};
      \path[lined] (d1) -- (a1);
      \path[lined] (d2) -- (a2);
      \path[lined] (d3) -- (a3);
      
      \node[box, fill=green!60!blue!80] at (3,-0.5) (ui) {监\\控\\界\\面};
      \node[box, fill=blue!25] at (1.5, 0.5) (a4) {actor4};
      \node[box, fill=blue!25] at (1.5, -0.5) (a5) {actor5};
      \node[box, fill=blue!25] at (1.5, -1.5) (a6) {actor6};
      
      \path[lined] (a1) -> (a4);
      \path[lined] (a2) -- (a5);
      \path[lined] (a3) -- (a6);
      
      \path[lined] (a4) -- (ui);
      \path[lined] (a5) -- (ui);
      \path[lined] (a6) -- (ui);
    \end{tikzpicture}
  \end{center}
  {\small actor1,actor2,actor3负责接收和发送3个被监控模块的监视信息和控制命令。} \\
  {\small actor4,actor5,actor6 负责管理被监控模块的界面元素状态信息，以及控制信息。} \\
  {\Large  每个actor只专注于自己对应的设备或者界面模块}
\end{frame}

\begin{frame} {调度系统}
  actor -> 被调度的软件/硬件/模块
  \begin{center}
    \begin{tikzpicture}
      % \draw[help lines, color=blue] (-8,-5) grid (0,0);
      % \draw[help lines] (0,0) grid (4,4);
      \node[box, fill=green!50, minimum width=6cm, minimum height=4cm] at(0,0) (m) {\ 调度系统 \\\\\\\\\\\\};
      \node[box, fill=blue!40] at (-3, -3) (d1) {被调度软件1};
      \node[box, fill=blue!40] at ( 0, -3) (d2) {被调度硬件2};
      \node[box, fill=blue!40] at ( 3, -3) (d3) {被调度模块3};
      
      \node[box, fill=blue!25] at (-1.7, -1.3) (a1) {actor1};
      \node[box, fill=blue!25] at (   0, -1.3) (a2) {actor2};
      \node[box, fill=blue!25] at ( 1.7, -1.3) (a3) {actor3};
      \path[lined] (d1) -- (a1);
      \path[lined] (d2) -- (a2);
      \path[lined] (d3) -- (a3);

      \node[box, fill=red!40, minimum width=4.5cm] at (0,0) (p) {调度流程};

      \path[line] (p) -- (a1);
      \path[line] (p) -- (a2);
      \path[line] (p) -- (a3);
      
    \end{tikzpicture}
  \end{center}
  
\end{frame}

\begin{frame} {并行计算}
  actor -> 算法子模块
  \begin{center}
    \begin{tikzpicture}
      % \draw[help lines, color=blue] (-8,-5) grid (0,0);
      % \draw[help lines] (0,0) grid (4,4);
      \node[box, fill=green!50, minimum width=7cm, minimum height=1.5cm] at(2,3) (ms) {\ map system \\\\};
      \node[box, fill=blue!25, minimum width=6cm] at (2,3) (p) {map};

      \node[box, fill=green!50, minimum width=3cm, minimum height=4cm] at(0,0) (m) {\ sytem1 \\\\\\\\\\\\\\};
      \node[box, fill=blue!25] at (0,  0.5) (a1) {actor1};
      \node[box, fill=blue!25] at (0, -0.5) (a2) {actor2};
      \node[box, fill=blue!25] at (0, -1.5) (a3) {actor3};
      \path[line] (p) -- (a1);
      \path[line] (p) -- (a2);
      \path[line] (p) -- (a3);
      
      \node[box, fill=green!50, minimum width=3cm, minimum height=4cm] at(4,0) (m) {\ sytem2 \\\\\\\\\\\\\\};
      \node[box, fill=blue!25] at (4,  0.5) (b1) {actor1};
      \node[box, fill=blue!25] at (4, -0.5) (b2) {actor2};
      \node[box, fill=blue!25] at (4, -1.5) (b3) {actor3};
      \path[line] (p) -- (b1);
      \path[line] (p) -- (b2);
      \path[line] (p) -- (b3);

      \node[box, fill=green!50, minimum width=7cm, minimum height=1.5cm] at(2,-3) (ms) {\\\\\\ reduce sytem};
      \node[box, fill=blue!25, minimum width=6cm] at (2,-3) (p) {recude};
      \path[line] (a1) -- (p);
      \path[line] (a2) -- (p);
      \path[line] (a3) -- (p);
      
      \path[line] (b1) -- (p);
      \path[line] (b2) -- (p);
      \path[line] (b3) -- (p);
    \end{tikzpicture}
  \end{center}
\end{frame}

\section{actor模型在Jvm系语言中的实现}

\begin{frame} {具体实现}
  \begin{itemize}
  \item AKKA:  \href{https://akka.io/}{https://akka.io/} \\
    AKKA支持java和scala语言。
  \item Vert.X: \href{https://vertx.io/}{https://vertx.io/} \\
    vertx支持java,kotlin, scala 等多个语言。
  \end{itemize}

\end{frame}

\end{document}